<template>
  <div class="content">
    <Form ref="form" :model="infos" :label-width="labelW" label-colon @submit.native.prevent>
      <template v-if="lineNumber">
        <Row :gutter="20">
          <Col
            :span="opt.col || 24 / lineNumber"
            v-if="opt.visible != false"
            v-for="opt in opts"
            :key="opt.key">
            <item
              ref="item"
              :option="opt"
              :info="infos"
              @change="onChange"
              @clearValidate="clearValidate"></item>
          </Col>
        </Row>
      </template>
      <template v-else>
        <Row v-for="(opts, idx) in opts" :key="idx" :gutter="20">
          <Col
            :span="opt.col || 24 / optLength(opts)"
            v-if="opt.visible != false"
            v-for="opt in Array.isArray(opts) ? opts : [opts]"
            :key="opt.key">
            <item
              ref="item"
              :option="opt"
              :info="infos"
              @change="onChange"
              @clearValidate="clearValidate"></item>
          </Col>
        </Row>
      </template>
    </Form>
  </div>
</template>

<script>
  import item from './dt-info-item.vue'
  import Opt from './Opt.js'

  export default {
    components: {
      item
    },
    props: {
      options: Array,
      lineNumber: Number, // opts 需为一维数组
      opt: Opt,
      info: Object,
      labelWidth: Number
    },
    computed: {
      labelW() {
        if (this.opts) {
          let max = null
          let set = (i) => {
            if (i.visible != false) {
              max = Math.max(i.labelWidth, max || 0)
            }
          }
          this.opts.forEach((i) => {
            if (Array.isArray(i)) {
              i.forEach((j) => {
                set(j)
              })
            } else {
              set(i)
            }
          })
          return max || this.labelWidth || 100
        }
        return 100
      }
    },
    watch: {
      options(n) {
        this.opts = n
      },
      opt(n) {
        this.opts = n.options()
      },
      info(n) {
        this.infos = n
      }
    },
    data() {
      return {
        isClear: false,
        opts: null,
        infos: null
      }
    },
    mounted() {
      if (this.options) {
        this.opts = this.options
      }
      if (this.opt) {
        this.opts = this.opt.options()
      }
      if (this.info) {
        this.infos = this.info
      }
    },
    methods: {
      init(opt, info) {
        this.infos = info
        if (opt.options) {
          this.opts = opt.options()
          if (opt.info) {
            this.infos = opt.info
          }
        } else {
          this.opts = opt
        }
      },
      validate() {
        return this.$refs.form.validate()
      },
      clear() {
        this.isClear = true
        let items = this.$refs.item
        if (items) {
          for (let item of items) {
            item.clear()
          }
        }
        this.$refs.form.resetFields()
        this.opts = null
        this.infos = null
      },
      resetFields() {
        this.isClear = true
        let items = this.$refs.item
        if (items) {
          for (let item of items) {
            item.clear()
          }
        }
        this.$refs.form.resetFields()
      },
      update() {
        this.isClear = false
        let items = this.$refs.item
        if (items) {
          for (let item of items) {
            item.update()
          }
        }
      },
      clearValidate(data) {
        setTimeout(() => {
          this.$refs.form.validateField(data)
        }, 500)
      },
      onChange(data) {
        if (!this.isClear) {
          if (data.option.rules) {
            setTimeout(() => {
              // 需要更新rules后才校验
              this.$refs.form.validateField(data.option.ruleKey || data.option.key)
              if (data.option.associationRules) {
                this.resetValidate(data.option.associationRules)
              }
            }, 100)
          }
          this.$emit('change', data)
        }
      },
      resetValidate(tarKeyArr) {
        // 重置部分表单验证
        for (let item of this.$refs.form.fields) {
          //form为表单的ref名称，fields为该表单下需要验证的所有字段，tarKeyArr为需要重置的所有字段
          if (tarKeyArr.indexOf(item.prop) !== -1) {
            item.resetField()
          }
        }
      },
      optLength(opts) {
        let num = 0
        if (Array.isArray(opts)) {
          opts.forEach((opt) => {
            if (opt.visible != false) {
              num++
            }
          })
        } else {
          num = 1
        }
        return num
      }
    }
  }
</script>

<style lang="scss" scoped>
  .content {
  }
</style>
